/**
 * @file    RGARunner.hpp
 * @brief   RGA工作线程类
 * @author  Haozhong Xu
 * @date    2025-05-27
 * @version 1.0
 * 
 * @note    接受RGA功能类和sharedbuffer，调用功能到buffer中
 */
#ifndef RGA_RUNNER_HPP
#define RGA_RUNNER_HPP

#include "runner/base_runner.hpp"
#include "rga/rga_converter.hpp"
#include "buffer/thread_safe_queue.hpp"
#include "buffer/frame.hpp"
#include "utils/log.hpp"

#include <memory>

/**
 * @class RGARunner
 * @brief RGARunner 工作线程类
 *
 * 接受RGA功能类对象和两个sharedBuffer，
 * 调用对象的功能处理buffer中的数据，之后存储到另一个
 * buffer中
 */
class RGARunner : public RunnerBase {
public:
    RGARunner(RGAConverter& converter,
              std::shared_ptr<ThreadSafeQueue<std::shared_ptr<Frame>>> input_queue,
              std::shared_ptr<ThreadSafeQueue<std::shared_ptr<Frame>>> output_queue)
        : RunnerBase("RGARunner"),
          _input_queue(std::move(input_queue)),
          _output_queue(std::move(output_queue)),
          _converter(converter) {}

protected:
    void Run() override {
        while (IsRunning()) {
            auto yuyv_frame = _input_queue->Pop();  // 阻塞直到拿到数据

            if (!yuyv_frame || yuyv_frame->format != FrameFormat::YUYV) {
                continue; // 格式不对或为空，跳过
            }

            // 关键的一步，目前是用初始化时申请的同一个dma区域进行色域转换
            if (!_converter.ConvertYUYVToRGB(yuyv_frame->data.data(), yuyv_frame->data.size())) {
                LOG_WARN("转换失败，跳过帧");
                continue;
            }

            auto rgb_frame = std::make_shared<Frame>();
            rgb_frame->width = yuyv_frame->width;
            rgb_frame->height = yuyv_frame->height;
            rgb_frame->format = FrameFormat::RGB;
            rgb_frame->timestamp = yuyv_frame->timestamp;

            const uint8_t* rgb_data = _converter.GetRGBData();
            size_t rgb_size = _converter.GetRGBDataSize();
            rgb_frame->data.assign(rgb_data, rgb_data + rgb_size);

            _output_queue->Push(rgb_frame);
        }
    }

private:
    RGAConverter &_converter;

    std::shared_ptr<ThreadSafeQueue<std::shared_ptr<Frame>>> _input_queue;
    std::shared_ptr<ThreadSafeQueue<std::shared_ptr<Frame>>> _output_queue;
};

#endif // RGA_RUNNER_HPP
